#include <iostream>
#include <string>
#include <random>
#include <ctime>
#include <cassert>
#include "TcpSocket.hpp"
#include "Protocol_1.hpp"

static const std::string opers = "+-*/%^~|";

void Usage(const std::string &proc)
{
    std::cout << std::endl;
    std::cout << " Usage: " << proc << " serveip serveport " << std::endl;
}

int main(int argc, char *argv[])
{
    srand(time(0));
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }
    std::string ip = argv[1];
    // std::cout << ip << std::endl;
    uint16_t port = std::stoi(argv[2]);
    // std::cout << port << std::endl;
    while (true) // 循环客服端服务
    {
        TcpSocket sock;
        sock.Socket(); // 创建套接字
        // bool ret_conet = sock.Connet(ip, port); //方案二的痕迹
        int recnt = 5; // 5次重连机会
        bool isreconnect = false;
        do
        {
            bool ret_conet = sock.Connet(ip, port);
            if (!ret_conet)
            {
                isreconnect = true;
                std::cout << "正在尝试重新连接...." << recnt << std::endl;
                recnt--;
                sleep(2);
            }
            else
                break;
        } while (recnt && isreconnect);
        // TcpSocket sock; //方案二的痕迹
        // sock.Socket(); // 创建套接字
        // bool ret_conet = sock.Connet(ip, port);
        // if(!ret_conet) exit(1);

        int cnt = 0;
        std::string inbuffer_stream;
        while (++cnt <= 10) // 10次任务请求
        {
            std::cout << "===============第" << cnt << "次测试....., " << "===============" << std::endl;
            int x = rand() % 101;
            usleep(6225);
            int y = rand() % 101;
            usleep(6328);
            char op = opers[rand() % opers.size()];
            Request req(x, y, op);
            req.DebugPrint(); // 打印发布的任务

            // 完成内容的序列化
            std::string package;
            req.Serialize(&package);
            Enpackage(package, &package);
            // std::cout << " &1 " << std::endl;

            int ret = write(sock.Getfd(), package.c_str(), package.size());
            if (ret > 0)
            {
                char buffer[128];
                ssize_t n = read(sock.Getfd(), buffer, sizeof(buffer)); // 我们也无法保证我们能读到一个完整的报文
                if (n > 0)
                {
                    buffer[n] = 0;
                    inbuffer_stream += buffer; // "len"\n"result code"\n
                    // std::cout << inbuffer_stream << std::endl;
                    std::string content;

                    bool r = Depackage(inbuffer_stream, &content); // "result code"
                    assert(r);

                    Response resp;
                    r = resp.Deserialize(content);
                    assert(r);

                    resp.DebugPrint();
                    std::cout << "=================================================" << std::endl;
                    sleep(1);
                }
                else
                {
                    std::cout << " &2 " << std::endl;
                    break;
                }
            }
            else
            {
                break;
            }
        }
    }
    // 填写服务端信息 进行连接
    // sock.Close();
    return 0;
}